package nz.ac.massey.groupproject.ecs2;

public class LinearBouncebackMotionSystem implements ECSSystem {

	public void tick(GameState gdata, ECSEntity ent, Position pos, LinearBouncebackMotion vel) {
		final int  MIN_X = gdata.MINX,  MAX_X = gdata.MAXX;
		final int  MIN_Y = gdata.MINY,  MAX_Y = gdata.MAXY;

		// speed cap    (otherwise bouncing back becomes a pain)
		if (vel.vx * 3 > (MAX_X - MIN_X))  vel.vx = (MAX_X - MIN_X) / 3;
		if (vel.vy * 3 > (MAX_Y - MIN_Y))  vel.vy = (MAX_Y - MIN_Y) / 3;

		// movement
		pos.x += vel.vx;
		pos.y += vel.vy;

		// bounce back  (Order of x and y doesn't matter)
		if (pos.x < MIN_X) { int xExcess = MIN_X - pos.x;   pos.x = MIN_X + xExcess;   vel.vx *= -1; }
		if (pos.x > MAX_X) { int xExcess = pos.x - MAX_X;   pos.x = MAX_X - xExcess;   vel.vx *= -1; }
		if (pos.y < MIN_Y) { int yExcess = MIN_Y - pos.y;   pos.y = MIN_Y + yExcess;   vel.vy *= -1; }
		if (pos.y > MAX_Y) { int yExcess = pos.y - MAX_Y;   pos.y = MAX_Y - yExcess;   vel.vy *= -1; }

		// obstacles    (TODO eventually this will replace the 4 world border checks)
		int collide = 1;
		for (var wall : gdata.walls) {
			var epoly = (PolygonComponent)  ent.get(PolygonComponent.class);
			var wpoly = (PolygonComponent) wall.get(PolygonComponent.class);
			var wpos  = (Position)         wall.get(Position        .class);

			var redzone = wpoly.poly;
			if (null != epoly) redzone = Polygon.minkowskiDiff(redzone, epoly.poly);
			var P = new Vec2l(pos.x - wpos.x, pos.y - wpos.y);

			collide = Math.min(collide, redzone.whereIs(P));
			if (collide < 0) break;
		}

		if (collide <= 0) {
			if (ent.has(Appearance.class))
				ent.set(collide < 0 ? Appearance.DEBUG_TINY_DOT1 : Appearance.DEBUG_TINY_DOT2);
			vel.vx = 0;
			vel.vy = 0;
		}
	}
}
